package transaction;

import java.rmi.Naming;
import java.rmi.RMISecurityManager;
import java.rmi.RemoteException;
import java.util.Collection;
import java.util.Iterator;

import lockmgr.DeadlockException;

/** 
 * Workflow Controller for the Distributed Travel Reservation System.
 * 
 * Description: toy implementation of the WC.  In the real
 * implementation, the WC should forward calls to either RM or TM,
 * instead of doing the things itself.
 */

public class WorkflowControllerImpl
    extends java.rmi.server.UnicastRemoteObject
    implements WorkflowController {

    protected int flightcounter, flightprice, carscounter, carsprice, roomscounter, roomsprice; 
    protected int xidCounter;
    
    protected ResourceManager rmFlights = null;
    protected ResourceManager rmRooms = null;
    protected ResourceManager rmCars = null;
    protected ResourceManager rmCustomers = null;
    protected ResourceManager rmReservations = null;
    protected TransactionManager tm = null;

    public static void main(String args[]) {
//	System.setSecurityManager(new RMISecurityManager());

	String rmiPort = System.getProperty("rmiPort");
//	String rmiPort = "1099";
	if (rmiPort == null) {
	    rmiPort = "";
	} else if (!rmiPort.equals("")) {
	    rmiPort = "//:" + rmiPort + "/";
	}

	try {
	    WorkflowControllerImpl obj = new WorkflowControllerImpl();
	    Naming.rebind("//localhost/" + WorkflowController.RMIName, obj);
	    System.out.println("WC bound");
	}
	catch (Exception e) {
	    System.err.println("WC not bound:" + e);
	    System.exit(1);
	}
    }
    
    
    public WorkflowControllerImpl() throws RemoteException, InterruptedException{
		flightcounter = 0;
		flightprice = 0;
		carscounter = 0;
		carsprice = 0;
		roomscounter = 0;
		roomsprice = 0;
		flightprice = 0;
	
		xidCounter = 1;
	
		while (!reconnect()) {
		    // would be better to sleep a while
			Thread.sleep(500);
		} 
    }


    // TRANSACTION INTERFACE
    public int start()
	throws RemoteException {
    	return tm.start();
    }

    public boolean commit(int xid)
	throws RemoteException, 
	       TransactionAbortedException, 
	       InvalidTransactionException {
    	try {
			tm.commit(xid);
		} catch (TransactionCommitFailedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	return true;
    }

    public void abort(int xid)
	throws RemoteException, 
               InvalidTransactionException {
    	try {
			tm.abort(xid);
		} catch (TransactionAbortedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	return;
    }


    // ADMINISTRATIVE INTERFACE
    public boolean addFlight(int xid, String flightNum, int numSeats, int price) 
	throws RemoteException, 
	       TransactionAbortedException,
	       InvalidTransactionException {
    	try {
			ResourceItem ri = rmFlights.query(xid, ResourceManager.RMINameFlights, flightNum);
			if(ri!=null)//exists
			{
				int preNumSeats = Integer.parseInt(ri.getIndex("numSeats").toString());
				int preNumAvail = Integer.parseInt(ri.getIndex("numAvail").toString());
				String [] colVals = new String []{flightNum,
						String.valueOf(price),
						String.valueOf(preNumSeats+numSeats),
						String.valueOf(preNumAvail+numSeats)};
				ResourceItem newri = RIFactory.getResourceItem(ResourceManager.RMINameFlights, flightNum, colVals);
				rmFlights.update(xid, ResourceManager.RMINameFlights, flightNum, newri);
			}
			else{
				String [] colVals = new String[]{flightNum,
						String.valueOf(price),
						String.valueOf(numSeats),
						String.valueOf(numSeats)};
				ResourceItem newri = RIFactory.getResourceItem(ResourceManager.RMINameFlights, flightNum, colVals);
				rmFlights.insert(xid, ResourceManager.RMINameFlights, newri);
			}
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
    	return true;
    }

    public boolean deleteFlight(int xid, String flightNum)
	throws RemoteException, 
	       TransactionAbortedException,
	       InvalidTransactionException {
    	try{
    		Collection c = rmReservations.query(xid, ResourceManager.RMINameReservations, "resvKey", flightNum);
    		if(c!=null&&!c.isEmpty())//exists resvs
    		{
    			return false;
    		}
    		rmFlights.delete(xid, ResourceManager.RMINameFlights, flightNum);
    	}catch(Exception e)
    	{
    		e.printStackTrace();
    		return false;
    	}
    	return true;
    }
		
    public boolean addRooms(int xid, String location, int numRooms, int price) 
	throws RemoteException, 
	       TransactionAbortedException,
	       InvalidTransactionException {
    	try {
			ResourceItem ri = rmRooms.query(xid, ResourceManager.RMINameRooms, location);
			if(ri!=null)//exists
			{
				int preNumRooms = Integer.parseInt(ri.getIndex("numRooms").toString());
				int preNumAvail = Integer.parseInt(ri.getIndex("numAvail").toString());
				String [] colVals = new String []{location,
						String.valueOf(price),
						String.valueOf(preNumRooms+numRooms),
						String.valueOf(preNumAvail+numRooms)};
				ResourceItem newri = RIFactory.getResourceItem(ResourceManager.RMINameRooms, location, colVals);
				rmRooms.update(xid, ResourceManager.RMINameRooms, location, newri);
			}
			else{
				String [] colVals = new String []{location,
						String.valueOf(price),
						String.valueOf(numRooms),
						String.valueOf(numRooms)};
				ResourceItem newri = RIFactory.getResourceItem(ResourceManager.RMINameRooms, location, colVals);
				rmRooms.insert(xid, ResourceManager.RMINameRooms, newri);
			}
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
    	return true;
    }

    public boolean deleteRooms(int xid, String location, int numRooms) 
	throws RemoteException, 
	       TransactionAbortedException,
	       InvalidTransactionException {
    	try{
    		ResourceItem ri = rmRooms.query(xid, ResourceManager.RMINameRooms, location);
    		if(ri==null)//don't exists
    			return false;
    		int preNumAvail = Integer.parseInt(ri.getIndex("numAvail").toString());
    		if(preNumAvail<numRooms)//not enough
    		{
    			return false;
    		}
    		int preNumRooms = Integer.parseInt(ri.getIndex("numRooms").toString());
    		String [] colVals = new String []{location,
					ri.getIndex("price").toString(),
					String.valueOf(preNumRooms-numRooms),
					String.valueOf(preNumAvail-numRooms)};
    		ResourceItem newri = RIFactory.getResourceItem(ResourceManager.RMINameRooms, location, colVals);
    		rmRooms.update(xid, ResourceManager.RMINameRooms, location, newri);
    	}catch(Exception e)
    	{
    		e.printStackTrace();
    		return false;
    	}
    	return true;
    }

    public boolean addCars(int xid, String location, int numCars, int price) 
	throws RemoteException, 
	       TransactionAbortedException,
	       InvalidTransactionException {
    	try {
			ResourceItem ri = rmCars.query(xid, ResourceManager.RMINameCars, location);
			if(ri!=null)//exists
			{
				int preNumCars = Integer.parseInt(ri.getIndex("numCars").toString());
				int preNumAvail = Integer.parseInt(ri.getIndex("numAvail").toString());
				String [] colVals = new String []{location,
						String.valueOf(price),
						String.valueOf(preNumCars+numCars),
						String.valueOf(preNumAvail+numCars)};
				ResourceItem newri = RIFactory.getResourceItem(ResourceManager.RMINameCars, location, colVals);
				rmCars.update(xid, ResourceManager.RMINameCars, location, newri);
			}
			else{
				String [] colVals = new String []{location,
						String.valueOf(price),
						String.valueOf(numCars),
						String.valueOf(numCars)};
				ResourceItem newri = RIFactory.getResourceItem(ResourceManager.RMINameCars, location, colVals);
				rmCars.insert(xid, ResourceManager.RMINameCars, newri);
			}
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
    	return true;
    }

    public boolean deleteCars(int xid, String location, int numCars) 
	throws RemoteException, 
	       TransactionAbortedException,
	       InvalidTransactionException {
    	try{
    		ResourceItem ri = rmCars.query(xid, ResourceManager.RMINameCars, location);
    		if(ri==null)//don't exists
    			return false;
    		int preNumAvail = Integer.parseInt(ri.getIndex("numAvail").toString());
    		if(preNumAvail<numCars)//not enough
    		{
    			return false;
    		}
    		int preNumCars = Integer.parseInt(ri.getIndex("numCars").toString());
    		String [] colVals = new String []{location,
					ri.getIndex("price").toString(),
					String.valueOf(preNumCars-numCars),
					String.valueOf(preNumAvail-numCars)};
    		ResourceItem newri = RIFactory.getResourceItem(ResourceManager.RMINameCars, location, colVals);
    		rmCars.update(xid, ResourceManager.RMINameCars, location, newri);
    	}catch(Exception e)
    	{
    		e.printStackTrace();
    		return false;
    	}
    	return true;
    }

    public boolean newCustomer(int xid, String custName) 
	throws RemoteException, 
	       TransactionAbortedException,
	       InvalidTransactionException {
    		try {
				String [] colVals = new String[]{custName};
				ResourceItem ri = RIFactory.getResourceItem(ResourceManager.RMINameCustomers, custName, colVals);
				return rmCustomers.insert(xid, ResourceManager.RMINameCustomers, ri);
			} catch (DeadlockException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				return false;
			}
    }

    public boolean deleteCustomer(int xid, String custName) 
	throws RemoteException, 
	       TransactionAbortedException,
	       InvalidTransactionException {
    	try {
			return rmCustomers.delete(xid, ResourceManager.RMINameCustomers, custName);
		} catch (DeadlockException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}
    }


    // QUERY INTERFACE
    public int queryFlight(int xid, String flightNum)
	throws RemoteException, 
	       TransactionAbortedException,
	       InvalidTransactionException {
    	int numAvail = -1;
    	try {
			ResourceItem ri = rmFlights.query(xid, ResourceManager.RMINameFlights, flightNum);
			if(ri==null) return -1;
			numAvail = Integer.parseInt(ri.getIndex("numAvail").toString());
		} catch (DeadlockException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return -1;
		} catch (NumberFormatException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return -1;
		} catch (InvalidIndexException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return -1;
		}
    	return numAvail;
    }

    public int queryFlightPrice(int xid, String flightNum)
	throws RemoteException, 
	       TransactionAbortedException,
	       InvalidTransactionException {
    	try {
			ResourceItem ri = rmFlights.query(xid, ResourceManager.RMINameFlights, flightNum);
			if(ri==null)return -1;
			return Integer.parseInt(ri.getIndex("price").toString());
		} catch (DeadlockException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return -1;
		} catch (NumberFormatException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return -1;
		} catch (InvalidIndexException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return -1;
		}
    }

    public int queryRooms(int xid, String location)
	throws RemoteException, 
	       TransactionAbortedException,
	       InvalidTransactionException {
    	int numAvail = -1;
    	try {
			ResourceItem ri = rmRooms.query(xid, ResourceManager.RMINameRooms, location);
			if(ri==null)return -1;
			numAvail = Integer.parseInt(ri.getIndex("numAvail").toString());
		} catch (DeadlockException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return -1;
		} catch (NumberFormatException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return -1;
		} catch (InvalidIndexException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return -1;
		}

    	return numAvail;
    }

    public int queryRoomsPrice(int xid, String location)
	throws RemoteException, 
	       TransactionAbortedException,
	       InvalidTransactionException {
    	try {
			ResourceItem ri = rmRooms.query(xid, ResourceManager.RMINameRooms, location);
			if(ri==null)return -1;
			return Integer.parseInt(ri.getIndex("price").toString());
		} catch (DeadlockException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return -1;
		} catch (NumberFormatException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return -1;
		} catch (InvalidIndexException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return -1;
		}
    }

    public int queryCars(int xid, String location)
	throws RemoteException, 
	       TransactionAbortedException,
	       InvalidTransactionException {
    	int numAvail = -1;
    	try {
			ResourceItem ri = rmCars.query(xid, ResourceManager.RMINameCars, location);
			if(ri==null)return -1;
			numAvail = Integer.parseInt(ri.getIndex("numAvail").toString());
		} catch (DeadlockException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return -1;
		} catch (NumberFormatException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return -1;
		} catch (InvalidIndexException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return -1;
		}

    	return numAvail;
    }

    public int queryCarsPrice(int xid, String location)
	throws RemoteException, 
	       TransactionAbortedException,
	       InvalidTransactionException {
    	try {
			ResourceItem ri = rmCars.query(xid, ResourceManager.RMINameCars, location);
			if(ri==null)return -1;
			return Integer.parseInt(ri.getIndex("price").toString());
		} catch (DeadlockException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return -1;
		} catch (NumberFormatException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return -1;
		} catch (InvalidIndexException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return -1;
		}
    }

    /*
     * @result -1 => no such customer
     * @result -2 => no such reservation
     * @result -3 => exception
     */
    public int queryCustomerBill(int xid, String custName)
	throws RemoteException, 
	       TransactionAbortedException,
	       InvalidTransactionException {
    	try {
			ResourceItem ri = rmCustomers.query(xid, ResourceManager.RMINameCustomers, custName);
			if(ri==null)return -1;
			Collection<?> c = rmReservations.query(xid, ResourceManager.RMINameReservations, "custName", custName);
			if(c==null)return -2;
			int bill = 0;
			Iterator<?> it = c.iterator();
			while(it.hasNext())
			{
				ri = (ResourceItem)it.next();
				String type = ri.getIndex("resvType").toString();
				Object key = ri.getIndex("resvKey");
				if(type.equals(ResourceManager.RMINameFlights))
				{
					bill += queryFlightPrice(xid, key.toString());
				}else if(type.equals(ResourceManager.RMINameCars))
				{
					bill += queryCarsPrice(xid, key.toString());
				}else if(type.equals(ResourceManager.RMINameRooms))
				{
					bill += queryRoomsPrice(xid, key.toString());
				}
			}
			
			return bill;

		} catch (DeadlockException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return -3;
		} catch (InvalidIndexException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return -3;
		}
    }


    // RESERVATION INTERFACE
    public boolean reserveFlight(int xid, String custName, String flightNum) 
	throws RemoteException, 
	       TransactionAbortedException,
	       InvalidTransactionException {
		try {
			ResourceItem ri = rmFlights.query(xid, ResourceManager.RMINameFlights, flightNum);
			if(ri==null)return false;
			if(Integer.parseInt(ri.getIndex("numAvail").toString())<=0)
			{
				return false;
			}
			int preNumAvail = Integer.parseInt(ri.getIndex("numAvail").toString());
			String [] colVals = new String []{flightNum,
					ri.getIndex("price").toString(),
					ri.getIndex("numSeats").toString(),
					String.valueOf(preNumAvail-1)};
			ResourceItem newFlightRi = RIFactory.getResourceItem(ResourceManager.RMINameFlights, flightNum, colVals);
			rmFlights.update(xid, ResourceManager.RMINameFlights, flightNum, newFlightRi);
			colVals = new String [] {custName+String.valueOf(xid), custName, ResourceManager.RMINameFlights, flightNum};
			ResourceItem newri = RIFactory.getResourceItem(ResourceManager.RMINameReservations, custName+String.valueOf(xid), colVals);
			rmReservations.insert(xid, ResourceManager.RMINameReservations, newri);
			return true;
		} catch (DeadlockException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		} catch (NumberFormatException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		} catch (InvalidIndexException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}
    }
 
    public boolean reserveCar(int xid, String custName, String location) 
	throws RemoteException, 
	       TransactionAbortedException,
	       InvalidTransactionException {
		try {
			ResourceItem ri = rmCars.query(xid, ResourceManager.RMINameCars, location);
			if(ri==null)return false;
			if(Integer.parseInt(ri.getIndex("numAvail").toString())<=0)
			{
				return false;
			}
			int preNumAvail = Integer.parseInt(ri.getIndex("numAvail").toString());
			String [] colVals = new String []{location,
					ri.getIndex("price").toString(),
					ri.getIndex("numCars").toString(),
					String.valueOf(preNumAvail-1)};
			ResourceItem newCarRi = RIFactory.getResourceItem(ResourceManager.RMINameCars, location, colVals);
			rmCars.update(xid, ResourceManager.RMINameCars, location, newCarRi);
			colVals = new String [] {custName+String.valueOf(xid), custName, ResourceManager.RMINameCars, location};
			ResourceItem newri = RIFactory.getResourceItem(ResourceManager.RMINameReservations, custName+String.valueOf(xid), colVals);
			rmReservations.insert(xid, ResourceManager.RMINameReservations, newri);
			return true;
		} catch (DeadlockException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		} catch (NumberFormatException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		} catch (InvalidIndexException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}
    }

    public boolean reserveRoom(int xid, String custName, String location) 
	throws RemoteException, 
	       TransactionAbortedException,
	       InvalidTransactionException {
		try {
			ResourceItem ri = rmRooms.query(xid, ResourceManager.RMINameRooms, location);
			if(ri==null)return false;
			if(Integer.parseInt(ri.getIndex("numAvail").toString())<=0)
			{
				return false;
			}
			int preNumAvail = Integer.parseInt(ri.getIndex("numAvail").toString());
			String [] colVals = new String []{location,
					ri.getIndex("price").toString(),
					ri.getIndex("numRooms").toString(),
					String.valueOf(preNumAvail-1)};
			ResourceItem newCarRi = RIFactory.getResourceItem(ResourceManager.RMINameRooms, location, colVals);
			rmRooms.update(xid, ResourceManager.RMINameRooms, location, newCarRi);
			colVals = new String [] {custName+String.valueOf(xid), custName, ResourceManager.RMINameRooms, location};
			ResourceItem newri = RIFactory.getResourceItem(ResourceManager.RMINameReservations, custName+String.valueOf(xid), colVals);
			rmReservations.insert(xid, ResourceManager.RMINameReservations, newri);
			return true;
		} catch (DeadlockException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		} catch (NumberFormatException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		} catch (InvalidIndexException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}
    }

    // TECHNICAL/TESTING INTERFACE
    public boolean reconnect()
	throws RemoteException {
	String rmiPort = System.getProperty("rmiPort");
	if (rmiPort == null) {
	    rmiPort = "";
	} else if (!rmiPort.equals("")) {
	    rmiPort = "//:" + rmiPort + "/";
	}

	try {
	    rmFlights =
		(ResourceManager)Naming.lookup(ResourceManager.RMINameFlights);
	    System.out.println("WC bound to RMFlights");
	    rmRooms =
		(ResourceManager)Naming.lookup(ResourceManager.RMINameRooms);
	    System.out.println("WC bound to RMRooms");
	    rmCars =
		(ResourceManager)Naming.lookup(ResourceManager.RMINameCars);
	    System.out.println("WC bound to RMCars");
	    rmCustomers =
		(ResourceManager)Naming.lookup(ResourceManager.RMINameCustomers);
	    System.out.println("WC bound to RMCustomers");
	    rmReservations =
		(ResourceManager)Naming.lookup(ResourceManager.RMINameReservations);
	    System.out.println("WC bound to RMReservations");
	    tm =
		(TransactionManager)Naming.lookup(TransactionManager.RMIName);
	    System.out.println("WC bound to TM");
	} 
	catch (Exception e) {
	    System.err.println("WC cannot bind to some component:" + e);
	    return false;
	}

	try {
	    if (rmFlights.reconnect() && rmRooms.reconnect() &&
		rmCars.reconnect() && rmCustomers.reconnect()) {
		return true;
	    }
	} catch (Exception e) {
	    System.err.println("Some RM cannot reconnect:" + e);
	    return false;
	}

	return false;
    }

    public boolean dieNow(String who)
	throws RemoteException {
		if (who.equals(TransactionManager.RMIName) ||
		    who.equals("ALL")) {
		    try {
			tm.dieNow();
		    } catch (RemoteException e) {}
		}
		if (who.equals(ResourceManager.RMINameFlights) ||
		    who.equals("ALL")) {
		    try {
			rmFlights.dieNow();
		    } catch (RemoteException e) {}
		}
		if (who.equals(ResourceManager.RMINameRooms) ||
		    who.equals("ALL")) {
		    try {
			rmRooms.dieNow();
		    } catch (RemoteException e) {}
		}
		if (who.equals(ResourceManager.RMINameCars) ||
		    who.equals("ALL")) {
		    try {
			rmCars.dieNow();
		    } catch (RemoteException e) {}
		}
		if (who.equals(ResourceManager.RMINameCustomers) ||
		    who.equals("ALL")) {
		    try {
			rmCustomers.dieNow();
		    } catch (RemoteException e) {}
		}
		if (who.equals(ResourceManager.RMINameReservations) ||
			    who.equals("ALL")) {
		    try {
		    	rmReservations.dieNow();
		    } catch (RemoteException e) {}
		}
		if (who.equals(WorkflowController.RMIName) ||
		    who.equals("ALL")) {
		    System.exit(1);
		}
		return true;
    }
    public boolean dieRMAfterEnlist(String who)
	throws RemoteException {
    	return true;
    }
    public boolean dieRMBeforePrepare(String who)
	throws RemoteException {
    	if (who.equals(ResourceManager.RMINameFlights) ||
    		    who.equals("ALL")) {
    		    try {
    		    	rmFlights.setDieTime("BeforePrepare");
    		    } catch (RemoteException e) {}
    		}
    		if (who.equals(ResourceManager.RMINameRooms) ||
    		    who.equals("ALL")) {
    		    try {
    		    	rmRooms.setDieTime("BeforePrepare");
    		    } catch (RemoteException e) {}
    		}
    		if (who.equals(ResourceManager.RMINameCars) ||
    		    who.equals("ALL")) {
    		    try {
    		    	rmCars.setDieTime("BeforePrepare");
    		    } catch (RemoteException e) {}
    		}
    		if (who.equals(ResourceManager.RMINameCustomers) ||
    		    who.equals("ALL")) {
    		    try {
    		    	rmCustomers.setDieTime("BeforePrepare");
    		    } catch (RemoteException e) {}
    		}
    		if (who.equals(ResourceManager.RMINameReservations) ||
    			    who.equals("ALL")) {
    		    try {
    		    	rmReservations.setDieTime("BeforePrepare");
    		    } catch (RemoteException e) {}
    		}
    		return true;
    }
    public boolean dieRMAfterPrepare(String who)
	throws RemoteException {
    	if (who.equals(ResourceManager.RMINameFlights) ||
		    who.equals("ALL")) {
		    try {
		    	rmFlights.setDieTime("AfterPrepare");
		    } catch (RemoteException e) {}
		}
		if (who.equals(ResourceManager.RMINameRooms) ||
		    who.equals("ALL")) {
		    try {
		    	rmRooms.setDieTime("AfterPrepare");
		    } catch (RemoteException e) {}
		}
		if (who.equals(ResourceManager.RMINameCars) ||
		    who.equals("ALL")) {
		    try {
		    	rmCars.setDieTime("AfterPrepare");
		    } catch (RemoteException e) {}
		}
		if (who.equals(ResourceManager.RMINameCustomers) ||
		    who.equals("ALL")) {
		    try {
		    	rmCustomers.setDieTime("AfterPrepare");
		    } catch (RemoteException e) {}
		}
		if (who.equals(ResourceManager.RMINameReservations) ||
			    who.equals("ALL")) {
		    try {
		    	rmReservations.setDieTime("AfterPrepare");
		    } catch (RemoteException e) {}
		}
		return true;
    }
    public boolean dieTMBeforeCommit()
	throws RemoteException {
	return true;
    }
    public boolean dieTMAfterCommit()
	throws RemoteException {
	return true;
    }
    public boolean dieRMBeforeCommit(String who)
	throws RemoteException {
    	if (who.equals(ResourceManager.RMINameFlights) ||
		    who.equals("ALL")) {
		    try {
		    	rmFlights.setDieTime("BeforeCommit");
		    } catch (RemoteException e) {}
		}
		if (who.equals(ResourceManager.RMINameRooms) ||
		    who.equals("ALL")) {
		    try {
		    	rmRooms.setDieTime("BeforeCommit");
		    } catch (RemoteException e) {}
		}
		if (who.equals(ResourceManager.RMINameCars) ||
		    who.equals("ALL")) {
		    try {
		    	rmCars.setDieTime("BeforeCommit");
		    } catch (RemoteException e) {}
		}
		if (who.equals(ResourceManager.RMINameCustomers) ||
		    who.equals("ALL")) {
		    try {
		    	rmCustomers.setDieTime("BeforeCommit");
		    } catch (RemoteException e) {}
		}
		if (who.equals(ResourceManager.RMINameReservations) ||
			    who.equals("ALL")) {
		    try {
		    	rmReservations.setDieTime("BeforeCommit");
		    } catch (RemoteException e) {}
		}
		return true;
    }
    public boolean dieRMBeforeAbort(String who)
	throws RemoteException {
    	if (who.equals(ResourceManager.RMINameFlights) ||
		    who.equals("ALL")) {
		    try {
		    	rmFlights.setDieTime("BeforeAbort");
		    } catch (RemoteException e) {}
		}
		if (who.equals(ResourceManager.RMINameRooms) ||
		    who.equals("ALL")) {
		    try {
		    	rmRooms.setDieTime("BeforeAbort");
		    } catch (RemoteException e) {}
		}
		if (who.equals(ResourceManager.RMINameCars) ||
		    who.equals("ALL")) {
		    try {
		    	rmCars.setDieTime("BeforeAbort");
		    } catch (RemoteException e) {}
		}
		if (who.equals(ResourceManager.RMINameCustomers) ||
		    who.equals("ALL")) {
		    try {
		    	rmCustomers.setDieTime("BeforeAbort");
		    } catch (RemoteException e) {}
		}
		if (who.equals(ResourceManager.RMINameReservations) ||
			    who.equals("ALL")) {
		    try {
		    	rmReservations.setDieTime("BeforeAbort");
		    } catch (RemoteException e) {}
		}
		return true;
    }
}
